#include "WebSocketServer.h"

Session::Session(tcp::socket&& socket,std::mutex& mutex)
    : ws_(std::move(socket)),mutex_(mutex)
{
    ws_.set_option(websocket::stream_base::timeout::suggested(boost::beast::role_type::server));
    ws_.set_option(websocket::stream_base::decorator([](websocket::request_type& req) {
        req.set(http::field::server, BOOST_BEAST_VERSION_STRING);
        }));
    //manager.run();
    //do_read();
}

Session::~Session() {
   
    close_connection();
    buffer_.consume(buffer_.size());
}

void Session::run() {
	ws_.async_accept(
		boost::bind(&Session::on_accept,
			shared_from_this(),
			boost::asio::placeholders::error));
	
}



void Session::on_accept(boost::system::error_code ec) {
    if (!ec) {
        do_read();
    }
    else
    {
        close_connection();
    }
}



void Session::do_read() {
	ws_.async_read(buffer_,
		boost::bind(&Session::on_read,
			shared_from_this(),
			boost::asio::placeholders::error,
			boost::asio::placeholders::bytes_transferred));
}

void Session::on_read(boost::system::error_code ec, std::size_t bytes_transferred) {
    boost::ignore_unused(bytes_transferred);

    if (!ec) {
        //std::lock_guard<std::mutex> guard(mutex_);
        std::string data(boost::asio::buffer_cast<const char*>(buffer_.data()), buffer_.size());
        //std::cout << "data: " << data << std::endl;
        send_response("Echo: " + data);
        process_data(data);
        buffer_.consume(buffer_.size());
        do_read();
    }else {
        close_connection();
        //std::cerr << "webSocket Error: " << ec.message() << std::endl;
    }
}

void Session::on_write(boost::beast::error_code ec, std::size_t bytes_transferred) {
    boost::ignore_unused(bytes_transferred);

    if (ec) {
        std::cerr << "webSocket Error: " << ec.message() << std::endl;
        close_connection();
    }
	buffer_.consume(buffer_.size());
	//do_read();
}

void Session::send_response(const std::string& response) {
    ws_.text(ws_.got_text());
    ws_.async_write(
        boost::asio::buffer(response),
        boost::beast::bind_front_handler(&Session::on_write,
            shared_from_this()));
}

void Session::close_connection() {
    if (ws_.is_open()) {
        ws_.close(websocket::close_code::normal);
    }
}

